﻿<html DIR="LTR" xmlns:tool="http://www.microsoft.com/tooltip" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:MSHelp="http://msdn.microsoft.com/mshelp">
  <head>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=utf-8" />
    <META NAME="save" CONTENT="history" />
    <title>Compreendendo transações XA</title>
    
    <link rel="stylesheet" type="text/css" href="../local/Classic.css">
      
    </link>
    
    <script src="../local/script.js">
      
    </script><script src="../local/script_main.js">&amp;nbsp;</script>
  </head>
  <body>
    <!--Topic built:04/01/2010 05:03:30-->

    
    
    
    
    
    
    
    
    
    <div id="header">
      <table width="100%" id="topTable"><tr>
          <td align="left">
            <span id="headerBold">Compreendendo transações XA</span>
          </td>
          <td align="right">
            
          </td>
        </tr></table>
      
      
      
    </div>
    <div id="mainSection">
      
        
        
    <font color="DarkGray">
      
    </font>
    <p />
    
    <p />
  
        <div id="introductionSection" class="section">
    <p>O Microsoft SQL Server JDBC Driver oferece suporte a transações distribuídas opcionais para Plataforma Java, Enterprise Edition/JDBC 2.0. Conexões JDBC obtidas da classe <a href="95fc7b07-2498-4a7e-8f7f-ee0d86b598b4.htm">SQLServerXADataSource</a> podem participar de ambientes de processamento de transações distribuídas padrão como os servidores de aplicativos da Plataforma Java, Enterprise Edition (Java EE). </p>
    <p>As classes para a implementação das transações distribuídas são as seguintes:</p>
    <table width="100%" cellspacing="0" cellpadding="0" border="1" style="background-color: #CCCCCC;"><tr>
          <th>
            Classe
          </th>
          <th>
            Implements
          </th>
          <th>
            Descrição
          </th>
        </tr><tr>
        <td>
          <p>com.microsoft.sqlserver.jdbc.SQLServerXADataSource</p>
        </td>
        <td>
          <p>javax.sql.XADataSource</p>
        </td>
        <td>
          <p>A fábrica de classes para conexões distribuídas.</p>
        </td>
      </tr><tr>
        <td>
          <p>com.microsoft.sqlserver.jdbc.SQLServerXAResource</p>
        </td>
        <td>
          <p>javax.transaction.xa.XAResource</p>
        </td>
        <td>
          <p>O adaptador de recursos para o gerenciador de transações.</p>
        </td>
      </tr></table>
    <div style="margin: .5em 1.5em .5em 1.5em"><b>Observação: </b>
      As conexões de transações distribuídas XA usam como padrão o nível de isolamento Leitura Confirmada.<p />
    </div>
  </div><h1 class="heading">Diretrizes e limitações ao usar transações XA</h1><div id="sectionSection0" class="section"><content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
      <p xmlns="">A lista a seguir fornece informações sobre limitações específicas e orientação quanto ao uso de transações XA:</p>
      <ul xmlns=""><li>
          No Windows XP:<br />
          Ao usar transações XA com o SQL Server pelo Microsoft SQL Server JDBC Driver, talvez você observe que elas podem não funcionar. Esse problema só se aplica quando o SQL Server que está participando da transação XA é executado no Windows XP. Por outro lado, os aplicativos cliente executados no Windows XP que se conectem a um SQL Server remoto que não é executado no Windows XP podem participar de transações XA. Para obter mais informações sobre como resolver esse problema, consulte um hotfix fornecido em <a href="http://support.microsoft.com/kb/922668" target="_blank" alt=""><linkText xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">Windows XP e transações XA</linkText></a>.<br />
        </li><li>
          No Windows Server 2003:<br />
          Ao usar transações XA junto com o MS DTC (Coordenador de Transações Distribuídas da Microsoft) no Windows Server 2003, talvez você observe que o método <b>XAResource.setTransactionTimeout</b> não funciona. Para resolver esse problema, você deve aplicar um hotfix fornecido em <a href="http://support.microsoft.com/kb/899756" target="_blank" alt=""><linkText xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">MSDTC e transações XA</linkText></a> a cada computador SQL Server que esteja participando das transações XA. Sem esse conserto (fix), o único valor de tempo limite válido é o valor padrão 0, ou seja, tempo limite infinito.<br />
        </li></ul>
      <p xmlns="">As diretrizes adicionais a seguir se aplicam a transações firmemente acopladas:</p>
      <ul xmlns=""><li>
          Ao usar transações XA junto com o MS DTC, talvez você observe que a versão atual do MS DTC não oferece suporte ao comportamento de ramificações XA firmemente acopladas. Por exemplo, o MS DTC tem um mapeamento um-para-um entre uma ID de transação de ramificação XA (XID) e uma ID de transação do MS DTC, e as operações executadas por ramificações XA frouxamente acopladas são isoladas uma da outra.<br />
          O hotfix fornecido em <a href="http://support.microsoft.com/kb/938653" target="_blank" alt=""><linkText xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">MSDTC e transações firmemente acopladas</linkText></a> habilita o suporte a ramificações XA firmemente acopladas em que várias ramificações XA com a mesma ID de transação global (GTRID) são mapeadas para uma única ID de transação do MS DTC. Esse suporte permite que várias ramificações XA firmemente acopladas vejam as alterações uma da outra no gerenciador de recursos, como o SQL Server.<br />
        </li><li>
          Um sinalizador <a href="379857c3-9de1-4964-8782-32df317cbfbb.htm">SSTRANSTIGHTLYCPLD</a>permite que os aplicativos usem as transações XA firmemente acopladas que têm IDs de transação de ramificação XA (XIDs) diferentes, mas a mesma ID de transação global (GTRID). Para usar esse recurso, você deve definir o sinalizador <a href="379857c3-9de1-4964-8782-32df317cbfbb.htm">SSTRANSTIGHTLYCPLD</a> no parâmetro <b>flags</b> do método <b>XAResource.start</b>:<br />
          <div class="sampleCode"><span codeLanguage="other"><pre>xaRes.start(xid, SQLServerXAResource.SSTRANSTIGHTLYCPLD);</pre></span></div>
        </li></ul>
    </content></div><h1 class="heading">Instruções de configuração</h1><div id="sectionSection1" class="section"><content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
      <p xmlns="">As etapas a seguir serão necessárias se você desejar usar fontes de dados XA junto com o MS DTC para tratar de transações distribuídas.</p>
      <div style="margin: .5em 1.5em .5em 1.5em" xmlns=""><b>Observação: </b>
        Os componentes de transações distribuídas do JDBC são incluídos no diretório xa da instalação do driver JDBC. Esses componentes incluem os arquivos xa_install.sql e sqljdbc_xa.dll.<p />
      </div>
    </content><sections xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
      <h1 class="heading" xmlns="">Executando o serviço MS DTC</h1><div id="sectionSection" class="section" xmlns=""><content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
          <p xmlns="">O serviço MS DTC deve ser marcado como <b>Automático</b> no Service Manager para garantir que ele esteja em execução quando o serviço SQL Server for iniciado. Para habilitar o MS DTC para transações XA, você deve seguir estas etapas:</p>
          <p xmlns="">No Windows XP e no Windows Server 2003:</p>
          <ol xmlns=""><li>
              No <b>Painel de Controle</b>, abra <b>Ferramentas Administrativas</b> e, em seguida, <b>Serviços de Componentes</b>. Você também pode clicar no botão <b>Iniciar</b>, clicar em <b>Executar</b>, digitar <b>dcomcnfg</b> na caixa <b>Abrir</b> e pressionar <b>OK</b> para abrir <b>Serviços de Componentes</b>.<br />
            </li><li>
              Expanda Serviços de Componentes, Computadores, clique com o botão direito do mouse em <b>Meu Computador</b> e selecione <b>Propriedades</b>.<br />
            </li><li>
              Clique na guia <b>MSDTC</b> e em <b>Configuração de Segurança</b>.<br />
            </li><li>
              Marque a caixa de seleção <b>Habilitar Transações XA</b> e clique em <b>OK</b>. Isso causará a reinicialização do serviço MS DTC.<br />
            </li><li>
              Clique em <b>OK</b> novamente para fechar a caixa de diálogo <b>Propriedades</b> e feche <b>Serviços de Componentes</b>.<br />
            </li><li>
              Pare e reinicie o SQL Server para assegurar que ele fique sincronizado com as alterações do MS DTC.<br />
            </li></ol>
          <p xmlns="">No Windows Vista:</p>
          <ol xmlns=""><li>
              Clique no botão <b>Iniciar</b>, digite <b>dcomcnfg</b> na caixa <b>Iniciar Pesquisa</b> e pressione ENTER para abrir <b>Serviços de Componentes</b>. Você também pode digitar %windir%\system32\comexp.msc na caixa <b>Iniciar</b> <b>Pesquisa</b> para abrir <b>Serviços de Componentes</b>.<br />
            </li><li>
              Expanda Serviços de Componentes, Computadores, Meu Computador e Coordenador de Transações Distribuídas.<br />
            </li><li>
              Clique com o botão direito do mouse em <b>DTC Local</b> e selecione <b>Propriedades</b>.<br />
            </li><li>
              Clique na guia <b>Segurança</b> na caixa de diálogo <b>Propriedades de DTC Local</b>.<br />
            </li><li>
              Marque a caixa de seleção <b>Habilitar Transações XA</b> e clique em <b>OK</b>. Isso causará a reinicialização do serviço MS DTC.<br />
            </li><li>
              Clique em <b>OK</b> novamente para fechar a caixa de diálogo <b>Propriedades</b> e feche <b>Serviços de Componentes</b>.<br />
            </li><li>
              Pare e reinicie o SQL Server para assegurar que ele fique sincronizado com as alterações do MS DTC.<br />
            </li></ol>
        </content></div>
      <h1 class="heading" xmlns="">Configurando os componentes de transações distribuídas do JDBC</h1><div id="sectionSection" class="section" xmlns=""><content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
          <p xmlns="">Você pode configurar os componentes de transações distribuídas do driver JDBC seguindo estas etapas:</p>
          <ol xmlns=""><li>
              Copie o arquivo sqljdbc_xa.dll do diretório de instalação do JDBC para o diretório Binn de cada computador SQL Server que participará de transações distribuídas.<br />
              <div style="margin: .5em 1.5em .5em 1.5em"><b>Observação: </b>
                 Se você estiver usando transações XA com um SQL Server de 32 bits, use o arquivo sqljdbc_xa.dll na pasta x86, mesmo que o SQL Server esteja instalado em um processador x64. Se estiver usando transações XA com um SQL Server de 64 bits no processador x64, use o arquivo sqljdbc_xa.dll na pasta x64. Se estiver usando transações XA com um SQL Server de 64 bits em um processador Itanium, use o arquivo sqljdbc_xa.dll na pasta IA64.<p />
              </div>
            </li><li>
              Execute o banco de dados script xa_install.sql em cada instância do SQL Server que participará de transações distribuídas. Esse script instala os procedimentos armazenados estendidos que são chamados por sqljdbc_xa.dll. Esses procedimentos armazenados estendidos implementam o suporte a transações distribuídas e XA para o Microsoft SQL Server JDBC Driver. Você precisará executar o script como administrador da instância do SQL Server.<br />
            </li><li>
              Para conceder permissões para um usuário específico participar de transações distribuídas com o driver JDBC, adicione o usuário à função SqlJDBCXAUser.<br />
            </li></ol>
          <p xmlns="">Só é possível configurar uma versão do assembly sqljdbc_xa.dll de cada vez em cada instância do SQL Server. Talvez os aplicativos precisem usar versões diferentes do driver JDBC para se conectar à mesma instância do SQL Server usando a conexão XA. Nesse caso, o arquivo sqljdbc_xa.dll, que vem com o driver JDBC mais recente, deve ser instalado na instância do SQL Server.</p>
          <p xmlns="">Há três maneiras de verificar qual versão de sqljdbc_xa.dll está instalada no momento na instância do SQL Server:</p>
          <ol xmlns=""><li>
              Abra o diretório LOG do computador SQL Server que participará de transações distribuídas. Selecione e abra o arquivo "ERRORLOG" do SQL Server. Procure a frase "Using 'SQLJDBC_XA.dll' version ..." no arquivo "ERRORLOG".<br />
            </li><li>
              Abra o diretório Binn do computador SQL Server que participará de transações distribuídas. Selecione o assembly sqljdbc_xa.dll. <br />
              <ol><li>
                  No Windows Vista: clique com o botão direito do mouse em sqljdbc_xa.dll e selecione Propriedades. Em seguida, clique na guia <b>Detalhes</b>. O campo <b>Versão do Arquivo</b> mostra a versão de sqljdbc_xa.dll que está instalada no momento na instância do SQL Server. <br />
                </li><li>
                  No Windows XP e no Windows 2003 Server: clique com o botão direito do mouse em sqljdbc_xa.dll e selecione Propriedades. Em seguida, clique na guia <b>Versão</b>. O campo <b>Versão do Arquivo</b> mostra a versão de sqljdbc_xa.dll que está instalada no momento na instância do SQL Server.<br />
                </li></ol>
            </li><li>
              Defina a funcionalidade de registro em log conforme mostrado no exemplo de código na próxima seção. Procure a frase "Server XA DLL version:..." no arquivo de log de saída.<br />
            </li></ol>
        </content></div>
      <h1 class="heading" xmlns="">Configurando as funções definidas pelo usuário</h1><div id="sectionSection" class="section" xmlns=""><content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
          <p xmlns="">Para conceder permissões para um usuário específico participar de transações distribuídas com o driver JDBC, adicione o usuário à função SqlJDBCXAUser. Por exemplo, use o código de Transact-SQL a seguir para adicionar um usuário nomeado 'shelby' (usuário com logon padrão do SQL chamado 'shelby') à função SqlJDBCXAUser:</p>
          <div class="sampleCode" xmlns=""><span codeLanguage="other"><pre>USE master
GO
EXEC sp_grantdbaccess 'shelby', 'shelby'
GO
EXEC sp_addrolemember [SqlJDBCXAUser], 'shelby'</pre></span></div>
          <p xmlns="">As funções definidas pelo usuário do SQL são definidas por banco de dados. Para criar sua própria função para fins de segurança, você terá que definir a função em cada banco de dados e adicionar os usuários para cada banco de dados. A função SqlJDBCXAUser é definida estritamente no banco de dados mestre porque é usada para conceder acesso aos procedimentos armazenados estendidos do SQL JDBC que residem no mestre. Primeiro será necessário conceder a usuários individuais acesso ao mestre, e então lhes conceder acesso à função SqlJDBCXAUser enquanto você está conectado ao banco de dados mestre.</p>
        </content></div>
    </sections></div><h1 class="heading">Exemplo</h1><div id="sectionSection2" class="section"><content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
      <div class="sampleCode" xmlns=""><span codeLanguage="other"><pre>import java.net.Inet4Address;
import java.sql.*;
import java.util.Random;
import javax.transaction.xa.*;
import javax.sql.*;
import com.microsoft.sqlserver.jdbc.*;

public class testXA {

   public static void main(String[] args) throws Exception {

      // Create variables for the connection string.
      String prefix = "jdbc:sqlserver://";
      String serverName = "localhost";
      int portNumber = 1433;
      String databaseName = "AdventureWorks"; 
      String user = "UserName"; 
      String password = "*****";
      String connectionUrl = prefix + serverName + ":" + portNumber
         + ";databaseName=" + databaseName + ";user=" + user + ";password=" + password;

      try {
         // Establish the connection.
         Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
         Connection con = DriverManager.getConnection(connectionUrl);

         // Create a test table.
         Statement stmt = con.createStatement();
         try {
            stmt.executeUpdate("DROP TABLE XAMin"); 
         }
         catch (Exception e) {
         }
         stmt.executeUpdate("CREATE TABLE XAMin (f1 int, f2 varchar(max))");
         stmt.close();
         con.close();

         // Create the XA data source and XA ready connection.
         SQLServerXADataSource ds = new SQLServerXADataSource();
         ds.setUser(user);
         ds.setPassword(password);
         ds.setServerName(serverName);
         ds.setPortNumber(portNumber);
         ds.setDatabaseName(databaseName);
         XAConnection xaCon = ds.getXAConnection();
         con = xaCon.getConnection();

         // Get a unique Xid object for testing.
         XAResource xaRes = null;
         Xid xid = null;
         xid = XidImpl.getUniqueXid(1);

         // Cleanup.
         con.close();
         xaCon.close();

         // Open a new connection and read back the record to verify that it worked.
         con = DriverManager.getConnection(connectionUrl);
         ResultSet rs = con.createStatement().executeQuery("SELECT * FROM XAMin");
         rs.next();
         System.out.println("Read -&gt; xid = " + rs.getString(2));
         rs.close();
         con.close();
      } 

      // Handle any errors that may have occurred.
      catch (Exception e) {
         e.printStackTrace();
      }
   }
}


class XidImpl implements Xid {

   public int formatId;
   public byte[] gtrid;
   public byte[] bqual;
   public byte[] getGlobalTransactionId() {return gtrid;}
   public byte[] getBranchQualifier() {return bqual;}
   public int getFormatId() {return formatId;}

   XidImpl(int formatId, byte[] gtrid, byte[] bqual) {
      this.formatId = formatId;
      this.gtrid = gtrid;
      this.bqual = bqual;
   }

   public String toString() {
      int hexVal;
      StringBuffer sb = new StringBuffer(512);
      sb.append("formatId=" + formatId);
      sb.append(" gtrid(" + gtrid.length + ")={0x");
      for (int i=0; i&lt;gtrid.length; i++) {
         hexVal = gtrid[i]&amp;0xFF;
         if ( hexVal &lt; 0x10 )
            sb.append("0" + Integer.toHexString(gtrid[i]&amp;0xFF));
         else
            sb.append(Integer.toHexString(gtrid[i]&amp;0xFF));
         }
         sb.append("} bqual(" + bqual.length + ")={0x");
         for (int i=0; i&lt;bqual.length; i++) {
            hexVal = bqual[i]&amp;0xFF;
            if ( hexVal &lt; 0x10 )
               sb.append("0" + Integer.toHexString(bqual[i]&amp;0xFF));
            else
               sb.append(Integer.toHexString(bqual[i]&amp;0xFF));
         }
         sb.append("}");
         return sb.toString();
      }

      // Returns a globally unique transaction id.
      static byte [] localIP = null;
      static int txnUniqueID = 0;
      static Xid getUniqueXid(int tid) {

      Random rnd = new Random(System.currentTimeMillis());
      txnUniqueID++;
      int txnUID = txnUniqueID;
      int tidID = tid;
      int randID = rnd.nextInt();
      byte[] gtrid = new byte[64];
      byte[] bqual = new byte[64];
      if ( null == localIP) {
         try {
            localIP = Inet4Address.getLocalHost().getAddress();
         }
         catch ( Exception ex ) {
            localIP =  new byte[] { 0x01,0x02,0x03,0x04 };
         }
      }
      System.arraycopy(localIP,0,gtrid,0,4);
      System.arraycopy(localIP,0,bqual,0,4);

      // Bytes 4 -&gt; 7 - unique transaction id.
      // Bytes 8 -&gt;11 - thread id.
      // Bytes 12-&gt;15 - random number generated by using seed from current time in milliseconds.
      for (int i=0; i&lt;=3; i++) {
         gtrid[i+4] = (byte)(txnUID%0x100);
         bqual[i+4] = (byte)(txnUID%0x100);
         txnUID &gt;&gt;= 8;
         gtrid[i+8] = (byte)(tidID%0x100);
         bqual[i+8] = (byte)(tidID%0x100);
         tidID &gt;&gt;= 8;
         gtrid[i+12] = (byte)(randID%0x100);
         bqual[i+12] = (byte)(randID%0x100);
         randID &gt;&gt;= 8;
      }
      return new XidImpl(0x1234, gtrid, bqual);
   }
}</pre></span></div>
    </content></div><span id="seeAlsoSpan"><h1 class="heading">Consulte também</h1></span><div id="seeAlsoSection" class="section" name="collapseableSection"><a href="afbb776f-05dc-4e79-bb25-2c340483e401.htm">Executando transações com o JDBC Driver</a><br /><br /></div><!--[if gte IE 5]>
			<tool:tip element="seeAlsoToolTip" avoidmouse="false"/><tool:tip element="languageFilterToolTip" avoidmouse="false"/><tool:tip element="roleInfoSpan" avoidmouse="false"/>
		<![endif]-->
      <div id="footer" class="section">
        
		<hr />
		
		<span id="fb" class="feedbackcss">
			
			
		</span>
		
		<a href="9bad553b-9e70-4696-8499-2e35f772a1e0.htm">
			
			© 2010 Microsoft Corporation. Todos os direitos reservados.
		</a>
 	
	
      </div>
    </div>
  </body>
</html>